/**
 * 北京通号模版
 *
 * Created by nongzhizhong on 2023/11/23.
 */
const fs = require('fs-extra');
const path = require('path');
const moment = require('moment');
const StaticAnalyzeDefaultReporter = require('../static-analyze-report');
const Task = require('../../../mongo/task');
const { type } = require('../../../tasks');
const rulesModels = require('../../../rules');

const defectStatusKey = {
  0: '待修改',
  1: '已修改',
  2: '忽略',
  3: '误报',
  4: '已说明',
};
class CrscStaticAnalyzeReporter extends StaticAnalyzeDefaultReporter {
  constructor(versionId, locale, version = null, project = null, creator = null, outputDir = null, format, filters = {}) {
    super(versionId, locale, version, project, creator, outputDir, format, filters, null, __dirname);
    this.taskFinishedTime = null;
  }

  /**
    * 过滤规则集数据
    * @param {Array[Object]} ruleSets 规则集
    * @param {Array[Object]} fileDefects 文件缺陷
    * @returns
    */
  handleDefectsByRuleSets(ruleSets, fileDefects) {
    return ruleSets
      // 只展示有缺陷的rule set
      .filter((set) => set.total)
      .map((set) => ({
        ...set,
        rules: set.levels.reduce((arr, lvl) => arr.concat(lvl.rules.map((r) => ({
          ...r,
          lvl: lvl.level,
          level: rulesModels.ruleLevelEum[r.originalLevel].name,
        }))), [])
          // 只展示有缺陷的rule
          .filter((r) => r.total)
          .map((v, index) => ({ ...v, index: index + 1 }))
          .reduce((ret, rule) => {
            let defects1;
            if (fileDefects) {
              defects1 = fileDefects.filter((d) => d.ruleId.equals(rule.ruleId))
                .map((defect, index) => ({
                  ...defect,
                  status: defectStatusKey[defect.status],
                  taskFinishedTime: this.taskFinishedTime,
                  researcher: this.creator.username,
                  ruleSetName: set.ruleSetName,
                  description: defect.description || '',
                  handleStatus: '已关闭',
                  index: index + 1,
                }));
              if (defects1.length > 0) {
                rule.total = defects1.length;
                ret[`level${rule.lvl}`].push({
                  ...rule,
                  defects: defects1,
                });
              }
            } else {
              ret[`level${rule.lvl}`].push({
                ...rule,
                defects: defects1,
              });
            }
            return ret;
          }, {
            level1: [], level2: [], level3: [],
          }),
      }));
  }

  /**
   * 处理单个文件，生成缺陷报告
   * @param {Object} file 单个文件信息
   * @param {String} versionDir 版本目录
   * @returns {Promise}
   */
  handleFile(file, versionDir) {
    return new Promise((resolve, reject) => {
      const fileName = `${file.fileName}静态编码规则违反问题报告单`;
      const reportPath = `${path.join(versionDir, path.dirname(file.path), fileName)}`;
      fs.ensureDir(path.dirname(reportPath))
        .then(async () => {
          if (!this.taskFinishedTime) {
            const task = await Task.findOne({ versionId: this.versionId, type: type.analyze }).sort({ _id: -1 });
            if (task) {
              this.taskFinishedTime = moment(task._id.getTimestamp()).format('YYYY-MM-DD HH:mm:ss');
            }
          }
          return Promise.resolve();
        })
        .then(() => this.generateDefectByFile(file))
        .then((allRulesBySet) => {
          const data = {
            fileName,
            allRulesBySet,
            reportName: fileName,
            ableReportCategory: this.ableReportCategory,
          };
          return this.generateFileReport(data, reportPath);
        })
        .then((reportPath) => {
          resolve({ reportPath });
        })
        .catch(reject);
    });
  }
}

/**
 * Export model definition object.
 */

module.exports = CrscStaticAnalyzeReporter;
